package spu

import (
	"context"
	"errors"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/shopspring/decimal"
	"github.com/spf13/cast"
	"insighttracking/apps/admin/internal/logic/category"
	"insighttracking/common/enum"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"
	"strings"

	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type CreateSpuApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewCreateSpuApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *CreateSpuApiLogic {
	hostname, _ := os.Hostname()
	return &CreateSpuApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *CreateSpuApiLogic) CreateSpuApi(req *types.CreateBaseSpuReq) (resp string, err error) {
	accountType := cast.ToInt64(l.ctx.Value("accountType"))
	if accountType != enum.EnterpriseEnum {
		return "", errors.New("只有企业账号才可以创建商品")
	}
	if req.SpuType != 0 {
		return "", errors.New("商品类型参数错误")
	}
	enterpriseId := cast.ToInt64(l.ctx.Value("enterpriseId"))
	salesPrice, _ := decimal.NewFromString(req.SalesPrice)
	lossRate, _ := decimal.NewFromString(req.LossRate)
	purchasePrice, _ := decimal.NewFromString(req.PurchasePrice)
	categoryIdList := k.Map(strings.Split(req.CategoryIDList, ","), func(item string, index int) int64 {
		return cast.ToInt64(item)
	})
	categoryLogic := category.NewGetCategoryListApiLogic(l.ctx, l.svcCtx, l.Request)
	categoryName, _ := categoryLogic.GetCategoryNameApi(categoryIdList)

	if err = dao.SpuEntity.WithContext(l.ctx).Create(&model.SpuEntity{
		EnterpriseID:    enterpriseId,                          // 关联到enterprise表主键id
		Name:            req.Name,                              // 商品名称
		SpuType:         req.SpuType,                           // 商品类型,0表示基础商品,1表示加工商品
		CategoryID:      categoryIdList[len(categoryIdList)-1], // 商品分类,只保存最后一级的
		CategoryName:    categoryName,                          // 单位分类名称
		CategoryIDList:  req.CategoryIDList,                    // 分类列表,多个用英文,拼接
		UnitID:          req.UnitID,                            // 单位,关联到unit表主键id
		IsWeighed:       req.IsWeighed,                         // 是否称重,0表示是,1表示否
		SalesPrice:      salesPrice,                            // 销售价
		Status:          req.Status,                            // 上架状态:1是上架,2是下架
		Sort:            req.Sort,                              // 排序
		ProductImageURL: req.ProductImageURL,                   // 商品图
		SupplierID:      req.SupplierID,                        // 供应商id
		BrandID:         req.BrandID,                           // 品牌id
		LossRate:        lossRate,                              // 损耗率
		PurchasePrice:   purchasePrice,                         // 采购价格
		Content:         req.Content,                           // 商品详情
		Spec:            req.Spec,                              // 规格
		Period:          req.Period,                            // 保质期
		IsSelfPurchase:  req.IsSelfPurchase,                    // 是否自备采购
	}); err != nil {
		return "", errors.New("创建失败")
	}
	return
}

func (l *CreateSpuApiLogic) CreateProcessSpuApi(req *types.CreateProcessSpuReq) (resp string, err error) {
	accountType := cast.ToInt64(l.ctx.Value("accountType"))
	if accountType != enum.EnterpriseEnum {
		return "", errors.New("只有企业账号才可以创建商品")
	}
	orgSpu, err := service.SpuService.GetBySpuIdApi(l.ctx, req.OrgSpuID)
	if err != nil || orgSpu.SpuType != 0 {
		return "", errors.New("原材料必须是基础商品")
	}
	if req.SpuType != 1 {
		return "", errors.New("商品类型参数错误")
	}

	enterpriseId := cast.ToInt64(l.ctx.Value("enterpriseId"))
	salesPrice, _ := decimal.NewFromString(req.SalesPrice)
	lossRate, _ := decimal.NewFromString(req.LossRate)
	purchasePrice, _ := decimal.NewFromString(req.PurchasePrice)
	categoryIdList := k.Map(strings.Split(req.CategoryIDList, ","), func(item string, index int) int64 {
		return cast.ToInt64(item)
	})
	categoryLogic := category.NewGetCategoryListApiLogic(l.ctx, l.svcCtx, l.Request)
	categoryName, _ := categoryLogic.GetCategoryNameApi(categoryIdList)

	spuEntity := model.SpuEntity{
		EnterpriseID:    enterpriseId,                          // 关联到enterprise表主键id
		Name:            req.Name,                              // 商品名称
		SpuType:         req.SpuType,                           // 商品类型,0表示基础商品,1表示加工商品
		CategoryID:      categoryIdList[len(categoryIdList)-1], // 商品分类,只保存最后一级的
		CategoryName:    categoryName,                          // 单位分类名称
		CategoryIDList:  req.CategoryIDList,                    // 分类列表,多个用英文,拼接
		UnitID:          req.UnitID,                            // 单位,关联到unit表主键id
		IsWeighed:       req.IsWeighed,                         // 是否称重,0表示是,1表示否
		SalesPrice:      salesPrice,                            // 销售价
		Status:          req.Status,                            // 上架状态:1是上架,2是下架
		Sort:            req.Sort,                              // 排序
		ProductImageURL: req.ProductImageURL,                   // 商品图
		SupplierID:      req.SupplierID,                        // 供应商id
		BrandID:         req.BrandID,                           // 品牌id
		LossRate:        lossRate,                              // 损耗率
		PurchasePrice:   purchasePrice,                         // 采购价格
		Content:         req.Content,                           // 商品详情
		Spec:            req.Spec,                              // 规格
		Period:          req.Period,                            // 保质期
		IsSelfPurchase:  req.IsSelfPurchase,                    // 是否自备采购
	}
	if err = dao.SpuEntity.WithContext(l.ctx).Create(&spuEntity); err != nil {
		return "", errors.New("创建失败")
	}

	entity := model.SpuBomEntity{
		EnterpriseID:      enterpriseId,
		Code:              req.Code,
		Name:              req.BomName,
		Describe:          req.Describe,
		OrgSpuID:          req.OrgSpuID,
		SpuID:             spuEntity.ID,
		OrgSpuName:        req.OrgSpuName,
		SpuName:           spuEntity.Name,
		ProductionLineIds: "," + req.ProductionLine + ",",
	}
	err = service.SpuService.CreateBom(l.ctx, &entity)
	return
}
